import 'dart:convert';

import 'package:pms_core/utils/log_util.dart';
import 'package:url_launcher/url_launcher_string.dart';

class UrlUtil {
  UrlUtil._();

  static final _instance = UrlUtil._();

  /// 与AppStore相关
  static const itunesUrl = 'https://itunes.apple.com';

  /// 与AppStore相关
  static const itunesApps = 'itms-apps://itunes.apple.com';

  /// 与AppStore相关
  static const itunesItms = 'itms://itunes.apple.com';

  /// 与Android应用市场相关 评分
  static const marketUrl = 'market://details?id=';

  /// 协议前缀
  /// 协议格式: laoyuegou://${schemeName}?result=${JSON.stringify(data)}
  /// rn格式: laoyuegou://${schemeName}?result=${JSON.stringify({routeName:'RNRoute',json:{}})}
  static const appPrefix = 'laoyuegou://';

  /// 跳转到指定scheme
  static void jump(String schemeUrl) => _instance._jump(schemeUrl);

  /// 未实现的协议回调
  static void Function(String scheme)? onUnimplementedScheme;

  Future<void> _jump(String schemeUrl) async {
    // itunes相关
    if (schemeUrl.startsWith(itunesUrl) ||
        schemeUrl.startsWith(itunesApps) ||
        schemeUrl.startsWith(itunesItms)) {
      if (await canLaunchUrlString(schemeUrl)) {
        await launchUrlString(schemeUrl);
      } else {
        logger.e("[UrlScheme] 无法打开: $schemeUrl");
      }
      return;
    }
    // 安卓应用市场market相关
    if (schemeUrl.startsWith(marketUrl)) {
      if (await canLaunchUrlString(schemeUrl)) {
        await launchUrlString(schemeUrl);
      } else {
        logger.e("[UrlSchemeHelper] 无法打开: $schemeUrl");
      }
      return;
    }
    final parsed = parseScheme(schemeUrl);
    if (parsed == null) {
      logger.e("[UrlSchemeHelper] 无效的协议: $schemeUrl");
      return;
    }

    final (:path, :data) = parsed;
    logger.t("[UrlScheme] 协议: $schemeUrl 参数: $data");

    switch ("$appPrefix$path") {
      default:
        // 未实现的协议
        onUnimplementedScheme?.call(schemeUrl);
        logger.w("[UrlScheme] 未实现协议: $schemeUrl");
    }
  }

  /// 解析协议
  static ({String path, Map<String, dynamic> data})? parseScheme(
      String schemeUrl) {
    final index = schemeUrl.indexOf('://');
    // 解析://之后的内容
    final uri = Uri.tryParse(schemeUrl, index + 3);
    if (uri == null) {
      return null;
    }

    final Uri(:path, :queryParameters) = uri;
    final query = _parseQueryParameters(queryParameters);
    return (path: path, data: query);
  }

  /// 从queryParameters中解析参数不存在时返回空map
  static Map<String, dynamic> _parseQueryParameters(
      Map<String, String> params) {
    final data = params['result'];
    if (data == null) {
      return {};
    }
    try {
      final json = jsonDecode(data);
      if (json is Map<String, dynamic>) {
        return json;
      }
    } catch (e) {
      logger.e("[UrlScheme] 解析参数失败: $data");
    }
    return {};
  }

  ///处理链接
  static void launchURL(String url) async {
    if (await canLaunchUrlString(url)) {
      await launchUrlString(url);
    } else {
      logger.e("暂不能处理这条链接:$url");
    }
  }
}
